﻿using Inaction.Criteria;
using Inaction.Mapping;
using System;
using System.Data;
using System.Linq.Expressions;

namespace Inaction.Business
{
    public partial class EntityList<T, Detail>
    {
        #region 方法
        public static T Query()
        {
            return Query((CriteriaBase)null);
        }

        public static T Query(CriteriaBase criteria)
        {
            var sql = Inaction.Mapping.EntitySqlStatement.GetSelectStatement<Detail>(criteria);
            return Query(sql);
        }

        public static T Query(IDbTransaction trans)
        {
            return Query(trans, (CriteriaBase)null);
        }

        public static T Query(IDbTransaction trans, CriteriaBase criteria)
        {
            var sql = Inaction.Mapping.EntitySqlStatement.GetSelectStatement<Detail>(criteria);
            return DoQuery(sql, trans);
        }

        public static T Query(Expression<Func<Detail, bool>> e)
        {
            var sql = Linq.LinqHelper<Detail>.CreateSelectSql(e);
            return Query(sql);
        }

        public static T Query(IDbTransaction trans, Expression<Func<Detail, bool>> e)
        {
            var sql = Linq.LinqHelper<Detail>.CreateSelectSql(e);
            return DoQuery(sql, trans);
        }

        public static T Query(int pageSize, int pageIndex)
        {
            return Query(pageSize, pageIndex, (CriteriaBase)null);
        }

        public static T Query(int pageSize, int pageIndex, Criteria.CriteriaBase criteria = null)
        {
            var sql = EntitySqlStatement.GetSelectStatement<Detail>(pageSize, pageIndex, criteria);
            return Query(sql);
        }

        public static T Query(IDbTransaction trans, int pageSize, int pageIndex)
        {
            return Query(trans, pageSize, pageIndex, (CriteriaBase)null);
        }

        public static T Query(IDbTransaction trans, int pageSize, int pageIndex, Criteria.CriteriaBase criteria = null)
        {
            var sql = EntitySqlStatement.GetSelectStatement<Detail>(pageSize, pageIndex, criteria);
            return DoQuery(sql, trans);
        }

        public static T Query(int pageSize, int pageIndex, Expression<Func<Detail, bool>> e)
        {
            var sql = EntitySqlStatement.GetSelectStatement<Detail>(pageSize, pageIndex, e);
            return Query(sql);
        }

        public static T Query(IDbTransaction trans, int pageSize, int pageIndex, Expression<Func<Detail, bool>> e)
        {
            var sql = EntitySqlStatement.GetSelectStatement<Detail>(pageSize, pageIndex, e);
            return DoQuery(sql, trans);
        }
        #endregion

        public void Refresh()
        {
            var temp = Query(this.sqlStatement);
            this.Clear();
            this.AddRange(temp);
        }

        #region 私有方法
        [NonSerialized]
        SqlStatement sqlStatement;

        [System.Xml.Serialization.XmlIgnore]
        public SqlStatement SqlStatement { get { return sqlStatement; } private set { sqlStatement = value; } }
        private static T Query(SqlStatement sql)
        {
            T t =  (T)Inaction.Proxy.Query(typeof(T), sql);
            t.SqlStatement = sql;
            return t;
        }

        private static T DoQuery(SqlStatement sql)
        {
            var list = new T();
            var items = Entity<Detail>.DoQuery(sql);
            foreach (var item in items)
            {
                list.Add(item);
                item.List = list;
            }
            return list;
        }

        private static T DoQuery(SqlStatement sql, IDbTransaction trans)
        {
            var list = new T();
            var items = Entity<Detail>.DoQuery(sql, trans);
            foreach (var item in items)
            {
                list.Add(item);
                item.List = list;
            }
            return list;
        }
        #endregion
    }
}